Skip to content

MDEV-40827: prefetch MHNSW neighbours during search - #5571

Open
chanztuying wants to merge 2 commits into
MariaDB:mainfrom
chanztuying:mdev-38721-prefetch
Open

MDEV-40827: prefetch MHNSW neighbours during search#5571
chanztuying wants to merge 2 commits into
MariaDB:mainfrom
chanztuying:mdev-38721-prefetch

Conversation

@chanztuying

Copy link
Copy Markdown

Summary

Prefetch unseen MHNSW neighbour allocations before their distance evaluations.

Correctness

  • Clean debug and release builds; the non-GNU #else path also compiles.
  • --do-test=vector and main.mysqld--help pass in both.
  • Exact brute-force recall is identical with and without the patch in every cell below.

Performance

Counterbalanced AB/BA, warm cache, both binaries querying the same persisted graph (200k x 1024, cosine, M=6); 200 queries, 30 paired observations per cell.
AMD EPYC 7713, RelWithDebInfo, 8-CPU cgroup quota on a shared host.

ef_search upstream prefetch paired median spe
40 1364.2 1518.2 +10.1% (+8.0%, +14.4%)
160 795.2 913.8 +13.8% (+11.8%, +20.0%)

The gain grows with ef_search: larger ef expands more nodes, so more neighbour groups are scanned and more memory latency is available to hide.

Issue prefetches for unseen neighbour nodes before evaluating their distances. This overlaps later memory loads with distance calculations for earlier lanes without changing the search result.

On a fixed 200k by 1024-dimensional cosine graph with M=6, a crossed AB/BA warm-cache run (30 paired observations) improved paired median QPS by 10.1% at ef_search=40 (95% CI 8.0%-14.4%) and 13.8% at ef_search=160 (95% CI 11.8%-20.0%), with identical exact-recall means.
@CLAassistant

CLAassistant commented Aug 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@gkodinov gkodinov added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label Aug 19, 2026
@gkodinov gkodinov self-assigned this Aug 19, 2026

@gkodinov gkodinov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! This is a preliminary review.

Please consider increasing the compiler coverage as suggested below. And stand by for the final review.

Comment thread sql/vector_mhnsw.cc Outdated
if (res == 0xff)
continue;

#if defined(__GNUC__)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please enable this for clang and msvc. This is what grok says should be done:

#if defined(__GNUC__) || defined(__clang__)
    __builtin_prefetch(link, 0, 3);   // rw: 0=read, 1=write; locality: 0–3
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
    #include <xmmintrin.h>   // or <intrin.h>
    _mm_prefetch((const char*)link, _MM_HINT_T0);   // _MM_HINT_T0, _MM_HINT_T1, _MM_HINT_T2, _MM_HINT_NTA
#else
    // no-op or do nothing
    (void)addr;
#endif

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also PreFetchCacheLine , which can be used just with _WIN32 , i.e does not depend on architecture

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also PreFetchCacheLine , which can be used just with _WIN32 , i.e does not depend on architecture

Good idea, added to make prefetch portable!

@gkodinov gkodinov assigned vuvova and unassigned gkodinov Aug 19, 2026
@gkodinov
gkodinov requested a review from vuvova August 19, 2026 07:34
@chanztuying

Copy link
Copy Markdown
Author

Addressed in the latest commit. Now supports GCC/Clang, MSVC x86/x64, and MSVC ARM64.

@chanztuying
chanztuying force-pushed the mdev-38721-prefetch branch 2 times, most recently from a651451 to c8da29b Compare August 21, 2026 17:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds portable CPU cache prefetching for unseen MHNSW neighbors during vector search.

Changes:

  • Prefetch neighbor allocations before distance evaluation.
  • Add cross-platform my_prefetch() support.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
sql/vector_mhnsw.cc Prefetches unseen MHNSW neighbors during search.
include/my_cpu.h Provides portable prefetch helper implementations.
Suppressed comments (1)

sql/vector_mhnsw.cc:1360

  • This assumes that the vector begins in the cache line immediately after the node's line, but the allocation is FVectorNode + gref + tref + vector, and the supported reference length can be much larger than one cache line. For such indexes this prefetch only warms the node/reference area; distance_to() still starts on a cold vector, so the optimization misses its target. Prefetch the actual vector address (using link->vec when loaded, otherwise derive it from tref() + tref_len() with FVector::align_ptr()).
          my_prefetch(link);
          my_prefetch(reinterpret_cast<const char*>(link)
                      + CPU_LEVEL1_DCACHE_LINESIZE);

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

6 participants